﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.ComponentModel;
using System.IO;
using System.Windows.Markup;
using System.Collections;
using System.Runtime.Serialization;
using XMLDataSerializer;
using FileFolder;
using Xceed.Wpf.DataGrid;

namespace ViCode_LeVi.Controls
{
    [DataContract]
    public class ListViewConfig
    {
        [DataMember]
        public double[] Widths { get; set; }
    }
    public class GetRowNumOrder : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return 0;
            ListViewItem listViewItem = (ListViewItem)value;
            ListView listView = ItemsControl.ItemsControlFromItemContainer(listViewItem) as ListView;
            // Get the index of a ListViewItem
            if (listViewItem == null || listView == null)
                return 0;
            int index = listView.ItemContainerGenerator.IndexFromContainer(listViewItem);
            return index + 1;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
    public static class ListViewHelper
    {
        #region EnsureDisplayItem
        public static void EnsureDisplayItem<T>(ListView lvw, Func<T, long> fGetID, long id)
        {
            if (lvw == null || fGetID == null)
                return;
            if (lvw.Items == null || lvw.Items.Count == 0)
                return;
            T[] data = lvw.Items.Cast<T>().ToArray();
            var focus = data.FirstOrDefault(d => fGetID(d) == id);
            if (focus != null)
                lvw.ScrollIntoView(focus);
        }
        public static void EnsureDisplayItem<T>(DataGridControl lvw, Func<T, long> fGetID, long id)
        {
            if (lvw == null || fGetID == null)
                return;
            if (lvw.Items == null || lvw.Items.Count == 0)
                return;
            T[] data = lvw.Items.Cast<T>().ToArray();
            var focus = data.FirstOrDefault(d => fGetID(d) == id);
            if (focus != null)
                lvw.BringItemIntoView(focus);
        }
        public static void EnsureDisplayItem<T>(ListView lvw, Func<T, bool> fCondition)
        {
            if (lvw == null || fCondition == null)
                return;
            if (lvw.Items == null || lvw.Items.Count == 0)
                return;
            T[] data = lvw.Items.Cast<T>().ToArray();
            var focus = data.FirstOrDefault(fCondition);
            if (focus != null)
                lvw.ScrollIntoView(focus);
        }
        public static void EnsureDisplayItem<T>(DataGridControl lvw, Func<T, bool> fCondition)
        {
            if (lvw == null || fCondition == null)
                return;
            if (lvw.Items == null || lvw.Items.Count == 0)
                return;
            T[] data = lvw.Items.Cast<T>().ToArray();
            var focus = data.FirstOrDefault(fCondition);
            if (focus != null)
                lvw.BringItemIntoView(focus);
        }
        #endregion
        public static void SetMinHeight(ListView lvw, double height)
        {
            GridView gridView = (GridView)lvw.View;
            if (gridView == null)
                return;
            if (gridView.Columns.Count == 0)
                return;

            GridViewColumn columnNumberOrder = new GridViewColumn();
            columnNumberOrder.Width = 0;
            FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(TextBlock));
            comboFactory.SetValue(TextBlock.MinHeightProperty, height);
            columnNumberOrder.CellTemplate = new DataTemplate() { VisualTree = comboFactory };

            gridView.Columns.Insert(gridView.Columns.Count, columnNumberOrder);

        }
        public static void AddColumnNumberOrder(ListView lvw)
        {
            GridView gridView = (GridView)lvw.View;
            if (gridView == null)
                return;
            if (gridView.Columns.Count == 0)
                return;
            GridViewColumn column = gridView.Columns[0];
            GridViewColumn columnNumberOrder = ListViewHelper.GetColumnNumberOrder();
            Binding old = (Binding)column.DisplayMemberBinding;
            Binding order = (Binding)columnNumberOrder.DisplayMemberBinding;

            //dk?
            if (old.RelativeSource == null)
            {
                gridView.Columns.Insert(0, columnNumberOrder);
            }
        }
        public const string HEADER_STT = "STT";
        public static GridViewColumn GetColumnNumberOrder()
        {
            GridViewColumn column = new GridViewColumn() { Header = HEADER_STT };
            Binding bd = new Binding();
            bd.RelativeSource =
                new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ListViewItem), 1);
            bd.Converter = new GetRowNumOrder();
            column.DisplayMemberBinding = bd;

            return column;
        }

        public static void SetupTextAlignment(TextAlignment textAlignment, params GridViewColumn[] columns)
        {
            foreach (GridViewColumn column in columns)
            {
                BindingBase orginal = column.DisplayMemberBinding;

                //Create Template with TextAlign = Right
                HierarchicalDataTemplate template = new HierarchicalDataTemplate();
                FrameworkElementFactory child_TextBlock = new FrameworkElementFactory(typeof(TextBlock));
                Debug.Assert(child_TextBlock != null);
                child_TextBlock.SetValue(TextBlock.TextAlignmentProperty, textAlignment);
                child_TextBlock.SetBinding(TextBlock.TextProperty, orginal);
                template.VisualTree = child_TextBlock;

                //Set template
                column.DisplayMemberBinding = null;
                column.CellTemplate = template;
            }
        }
        public static void SetupInvisibleColumns(this ListView listView, params GridViewColumn[] columns)
        {
            GridView gv = listView.View as GridView;
            if (gv != null)
            {
                foreach (var clm in columns)
                    gv.Columns.Remove(clm);
            }
        }

        public static T CheckDoubleClickOnListViewItem<T>(this ListView lvw, MouseButtonEventArgs e) where T : class
        {
            DependencyObject dep = (DependencyObject)e.OriginalSource;

            while ((dep != null) && !(dep is ListViewItem))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }

            if (dep == null)
                return null;

            try
            {
                T item = (T)lvw.ItemContainerGenerator.ItemFromContainer(dep);
                return item;
            }
            catch
            { return null; }
        }

        #region AutoWidth
        /// <summary>
        /// Các thông tin về Width sẽ được lưu xuống file cấu hình
        /// </summary>
        public static void SetupListViewConfig()
        {
            EventManager.RegisterClassHandler(typeof(UserControl),
                 UserControl.LoadedEvent,
                 new RoutedEventHandler(UserControl_Loaded));
            EventManager.RegisterClassHandler(typeof(UserControl),
                 UserControl.UnloadedEvent,
                 new RoutedEventHandler(UserControl_UnLoaded));

            //Khong bat dc 2 su kien duoi
            EventManager.RegisterClassHandler(typeof(ListView),
                 ListView.LoadedEvent,
                 new RoutedEventHandler(ListView_Loaded));
            EventManager.RegisterClassHandler(typeof(ListView),
                 ListView.UnloadedEvent,
                 new RoutedEventHandler(ListView_UnLoaded));
        }
        static string GetListViewPathConfig(this UIElement lvw)
        {
            string sFolder = "ListViewConfig";
            string file = DependencyHelper.GetPathVisual(lvw);
            file = file.Replace("ContainerPanel", "").Replace("AdornerDecorator", "").Replace("ContentPresenter", "").Replace("Border", "");
            //Phải remove windows ve lúc unload nó ko còn windows
            file = file.Replace("Window", "");
            file = file.Replace('.', '_');
            file = file.Replace("__", "_");
            file = file.Replace("__", "_");
            file = file.Trim('_');
            if (file.Length > 127)
                file = file.Substring(file.Length - 79);

            string sPathFlder = FileFolder.AppInfo.AppDirectory + "\\" + sFolder;
            string path = sPathFlder + "\\" + file + ".lvwConfig";

            if (path.Length >= 200)
                file = file.Replace("_", "");
            path = sPathFlder + "\\" + file + ".lvwConfig";

            if (path.Length >= 200)
            {
                file = file.Replace("DockPanel", "");
                file = file.Replace("StackPanel", "");
                file = file.Replace("Grid", "");
                file = file.Replace("GroupBox", "");
                file = file.Replace("Border", "");
            }
            path = sPathFlder + "\\" + file + ".lvwConfig";

            FolderHelper.EnsureExistFolder(sPathFlder);
            if (!File.Exists(path))
                File.Create(path);
            return path;
        }
        public static ListViewConfig GetConfig(DependencyObject obj)
        {
            return (ListViewConfig)obj.GetValue(ConfigProperty);
        }

        public static void SetConfig(DependencyObject obj, ListViewConfig value)
        {
            obj.SetValue(ConfigProperty, value);
        }

        // Using a DependencyProperty as the backing store for Config.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ConfigProperty =
            DependencyProperty.RegisterAttached("Config", typeof(ListViewConfig), typeof(UIElement), new UIPropertyMetadata(null));

        static void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            UserControl uc = (UserControl)sender;
            Debug.Assert(uc != null);
            RefreshListViewColumnWidthWithConfig(uc);
        }
        public static bool Save_DataGridControl_Setting = false;
        public static void RefreshListViewColumnWidthWithConfig(UserControl uc)
        {
            var lvws = uc.GetVisualOfType<ListView>();
            if (lvws != null)
            {
                foreach (ListView lvw in lvws)
                {
                    string path = lvw.GetListViewPathConfig();
                    ListViewConfig config = XMLData<ListViewConfig>.GetEntity(path);
                    if (config == null)
                        return;
                    //Set width
                    GridView gv = (GridView)lvw.View;
                    if (config.Widths != null && gv != null)
                    {
                        int i = 0;
                        //Bỏ đi cột STT đầu tiên
                        int iExt = 0;
                        if (gv.Columns.Count > 0)
                            if (gv.Columns[0].IsColumnOrder())
                            {
                                iExt = 1;
                            }
                        while ((i - iExt) < config.Widths.Length && i < gv.Columns.Count)
                        {
                            if (i - iExt > 0)
                                gv.Columns[i].Width = config.Widths[i - iExt];
                            i++;
                        }
                    }
                }
            }
            if (Save_DataGridControl_Setting == true)
            {
                var xcdgs = uc.GetVisualOfType<DataGridControl>();
                if (xcdgs != null)
                {
                    foreach (var dtg in xcdgs)
                    {
                        string path = dtg.GetListViewPathConfig();
                        ListViewConfig config = XMLData<ListViewConfig>.GetEntity(path);
                        if (config == null)
                            return;
                        //Set width
                        int i = 0;
                        foreach (var clm in dtg.Columns)
                        {
                            if (config.Widths.Length < i)
                                clm.Width = config.Widths[i];
                            else
                            {
#warning Save to logfile to watch error
                                break;
                            }
                            i++;
                        }
                    }
                }
            }
        }
        public static bool IsColumnOrder(this GridViewColumn cln)
        {
            return cln != null && cln.Header != null && cln.Header.ToString() == HEADER_STT;
        }
        static void UserControl_UnLoaded(object sender, RoutedEventArgs e)
        {
            UserControl uc = (UserControl)sender;
            Debug.Assert(uc != null);
            var lvws = uc.GetVisualOfType<ListView>();
            if (lvws != null)
            {
                foreach (ListView lvw in lvws)
                {
                    string path = lvw.GetListViewPathConfig();
                    try
                    {
                        if (File.Exists(path))
                            File.Delete(path);
                    }
                    catch { }
                    //Get width
                    List<double> listSize = new List<double>();
                    GridView gv = (GridView)lvw.View;
                    foreach (var c in gv.Columns)
                        if (!c.IsColumnOrder())
                            listSize.Add(c.ActualWidth);
                    ListViewConfig config = new ListViewConfig();
                    config.Widths = listSize.ToArray();
                    try
                    {
                        File.Delete(path);
                    }
                    catch
                    { }
                    bool bResult = XMLData<ListViewConfig>.SaveEntity(path, config);
                    if (bResult == false)
                    {
                        Console.WriteLine("Không lưu được cấu hình ListView vào " + path);
                    }
                }
            }

            if (Save_DataGridControl_Setting != null)
            {
                var xdgs = uc.GetVisualOfType<DataGridControl>();
                if (xdgs != null)
                {
                    ThreadHelper.Runner.RunAfterUIAction(uc, () =>
                    {
                        foreach (var dtg in xdgs)
                        {
                            ThreadHelper.Runner.RunInBackground(() =>
                            {
                                string path = string.Empty;
                                List<double> listSize = new List<double>();
                                ThreadHelper.Runner.RunInMainThread(() =>
                                {
                                    path = dtg.GetListViewPathConfig();
                                    try
                                    {
                                        if (File.Exists(path))
                                            File.Delete(path);
                                    }
                                    catch { }
                                    //Get width                           
                                    foreach (var c in dtg.Columns)
                                        listSize.Add(c.Width);
                                });
                                ListViewConfig config = new ListViewConfig();
                                config.Widths = listSize.ToArray();
                                try
                                {
                                    File.Delete(path);
                                }
                                catch
                                { }
                                bool bResult = XMLData<ListViewConfig>.SaveEntity(path, config);
                                if (bResult == false)
                                {
                                    Console.WriteLine("Không lưu được cấu hình ListView vào " + path);
                                }
                            });
                        }
                    }, System.Windows.Threading.DispatcherPriority.SystemIdle);
                }
            }
        }
        static void ListView_Loaded(object sender, RoutedEventArgs e)
        {
            ListView lvw = (ListView)sender;
            Debug.Assert(lvw != null);
            string path = lvw.GetListViewPathConfig();

            List<double> listSize = new List<double>();
            GridView gv = (GridView)lvw.View;
            foreach (var c in gv.Columns)
                listSize.Add(c.ActualWidth);
            //ConfigStockInput.ListViewIODetailWidth = listSize.ToArray();
        }
        static void ListView_UnLoaded(object sender, RoutedEventArgs e)
        {
            (sender as TextBox).SelectAll();
        }

        public static void SetupAutoWidth(this ListView listView)
        {
            //DependencyPropertyDescriptor myDescriptor = DependencyPropertyDescriptor.FromProperty(ListView.ItemsSourceProperty, typeof(ListView));
            //myDescriptor.AddValueChanged(listView, new EventHandler(ItemSourceChanged));
        }
        private static void ItemSourceChanged(Object sender, EventArgs e)
        {
            RefreshAutoWidth(sender as ListView);
        }
        public static void RefreshAutoWidth(ListView listView)
        {
            listView.Items.Refresh();
            if (listView == null)
                return;
            GridView gv = listView.View as GridView;
            if (gv == null)
                return;
            listView.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Auto);
            foreach (GridViewColumn gvc in gv.Columns)
            {
                gvc.Width = gvc.ActualWidth;
                gvc.Width = Double.NaN;//System.Windows.GridLength.Auto;
            }
        }
        #endregion


        #region ListView with CheckBox

        #region Extension Method  For ListView



        /// <summary>
        /// Set Enable For Checkbox
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="headerOfColumn"> Header Of Column </param>
        public static void SetEnableForCheckBox(this ListView listView, int columnIndex, Boolean isEnable)
        {
            for (int i = 0; i < listView.Items.Count; i++)
            {
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                SupportCheckBoxTag support = GetTagOfListViewItem(lvItem);
                support.IsEnabled = isEnable;
                lvItem.Tag = support;

            }

        }



        /// <summary>
        /// Append Column Checkbox
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="headerOfColumn"> Header Of Column </param>
        public static void SetupCheckboxColumn(this ListView listView, object headerOfColumn)
        {
            SetupCheckboxColumn(listView, 0, headerOfColumn);
        }




        /// <summary>
        /// Append Column CheckBox with IndexColumn and headerColumn
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="indexColumn">index of Column want to append</param>
        /// <param name="headerOfColumn"> header of Column</param>
        public static void SetupCheckboxColumn(this ListView listView, int indexColumn, object headerOfColumn)
        {
            GridView gridView = listView.View as GridView;
            GridViewColumn gridViewColumn = GetGridViewColumnCheckBox();
            gridViewColumn.Header = headerOfColumn;
            gridView.Columns.Insert(indexColumn, gridViewColumn);

        }

        /// <summary>
        /// Get Selected Indices List 
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="indexArray"></param>
        public static int[] GetCheckedIndices(this ListView listView)
        {
            List<int> indexList = new List<int>();
            for (int i = 0; i < listView.Items.Count; i++)
            {
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
                {
                    SupportCheckBoxTag support = (SupportCheckBoxTag)lvItem.Tag;
                    if (support.IsChecked == true)
                    {
                        indexList.Add(i);
                    }
                }
            }
            return indexList.ToArray();
        }


        /// <summary>
        /// Get Checked Values
        /// </summary>
        /// <param name="listView"></param>
        /// <returns></returns>
        public static ArrayList GetCheckedValues(this ListView listView)
        {
            ArrayList valuesList = new ArrayList();
            for (int i = 0; i < listView.Items.Count; i++)
            {
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
                {
                    SupportCheckBoxTag support = (SupportCheckBoxTag)lvItem.Tag;
                    if (support.IsChecked == true)
                    {
                        valuesList.Add(lvItem.Content);
                    }
                }
            }
            return valuesList;
        }

        public static TEntity[] GetCheckEntities<TEntity>(this ListView listView) where TEntity : class
        {
            List<TEntity> entiies = new List<TEntity>();
            for (int i = 0; i < listView.Items.Count; i++)
            {
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
                {
                    SupportCheckBoxTag support = (SupportCheckBoxTag)lvItem.Tag;
                    if (support.IsChecked == true)
                    {
                        entiies.Add(lvItem.Content as TEntity);
                    }
                }
            }
            return entiies.ToArray();
        }
        private static SupportCheckBoxTag GetTagOfListViewItem(ListViewItem lvItem)
        {
            SupportCheckBoxTag support = null;
            if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
            {
                support = (SupportCheckBoxTag)lvItem.Tag;
            }
            else
            {
                support = new SupportCheckBoxTag();
            }
            return support;
        }

        /// <summary>
        /// Set Checked With indices Array
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="indexArray"></param>
        public static void SetCheckedWithIndicesList(this ListView listView, int[] indexArray)
        {
            List<int> listIndex;
            if (indexArray == null)
                listIndex = new List<int>();
            else
                listIndex = new List<int>(indexArray);
            for (int i = 0; i < listView.Items.Count; i++)
            {
                Boolean isChecked = false;
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
                if (lvItem != null)
                {
                    //SupportCheckBoxTag support = null ;
                    //if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
                    //{
                    //    support = (SupportCheckBoxTag)lvItem.Tag;
                    //}
                    //else
                    //{
                    //    support = new SupportCheckBoxTag();
                    //}
                    SupportCheckBoxTag support = GetTagOfListViewItem(lvItem);

                    if (listIndex.IndexOf(i) >= 0)
                    {
                        isChecked = true;
                    }

                    support.IsChecked = isChecked;
                    lvItem.Tag = support;
                    //if (listIndex.IndexOf(i) >= 0)
                    //    isChecked = true;
                    //lvItem.Tag = isChecked;
                }


            }
        }

        public static void SetCheckedWithEntitiesList<TEntity>(this ListView listView, IEnumerable<TEntity> listEntitiesCheck,
                                            Func<TEntity, TEntity, bool> funcCompare) where TEntity : class
        {
            if (funcCompare == null)
            {
                listView.SetCheckedWithEntitiesList(listEntitiesCheck);
            }
            for (int i = 0; i < listView.Items.Count; i++)
            {
                Boolean isChecked = false;
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
                if (lvItem != null)
                {
                    TEntity tentity = (TEntity)lvItem.Content;
                    var colection = from te in listEntitiesCheck
                                    where (funcCompare(tentity, te))
                                    select te;

                    //SupportCheckBoxTag support = null;
                    //if (lvItem != null && lvItem.Tag != null && lvItem.Tag.GetType() == typeof(SupportCheckBoxTag))
                    //{
                    //    support = (SupportCheckBoxTag)lvItem.Tag;
                    //}
                    //else
                    //{
                    //    support = new SupportCheckBoxTag();
                    //}
                    SupportCheckBoxTag support = GetTagOfListViewItem(lvItem);

                    if (colection.Count() > 0)
                    {
                        isChecked = true;
                    }

                    support.IsChecked = isChecked;
                    lvItem.Tag = support;

                    //if (colection.Count() > 0)
                    //    isChecked = true;
                    //lvItem.Tag = isChecked;
                }
            }

        }

        /// <summary>
        /// Set Checked With Condition
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="listView"></param>
        /// <param name="funcCompare"></param>
        public static void SetCheckedWithFunc<TEntity>(this ListView listView, Func<TEntity, bool> funcCompare) where TEntity : class
        {
            if (funcCompare == null)
            {
                return;
            }
            for (int i = 0; i < listView.Items.Count; i++)
            {
                Boolean isChecked = false;
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
                if (lvItem != null)
                {
                    TEntity tentity = (TEntity)lvItem.Content;

                    SupportCheckBoxTag support = GetTagOfListViewItem(lvItem);

                    if (funcCompare(tentity))
                    {
                        isChecked = true;
                    }

                    support.IsChecked = isChecked;
                    lvItem.Tag = support;

                    //if (funcCompare(tentity))
                    //    isChecked = true;
                    //lvItem.Tag = isChecked;
                }
            }

        }


        /// <summary>
        /// Set Checked With indices Array
        /// </summary>
        /// <param name="listView"></param>
        /// <param name="indexArray"></param>
        public static void SetCheckedWithEntitiesList<TEntity>(this ListView listView, IEnumerable<TEntity> listEntitiesCheck)
        {
            if (listEntitiesCheck == null)
                return;
            for (int i = 0; i < listView.Items.Count; i++)
            {
                Boolean isChecked = false;
                ListViewItem lvItem = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
                if (lvItem != null)
                {
                    TEntity tentity = (TEntity)lvItem.Content;
                    ArrayList array = new ArrayList(listEntitiesCheck.ToArray());

                    SupportCheckBoxTag support = GetTagOfListViewItem(lvItem);


                    if (array.IndexOf(tentity) >= 0)
                        isChecked = true;

                    support.IsChecked = isChecked;
                    lvItem.Tag = support;

                    //if (array.IndexOf(tentity) >= 0)
                    //{
                    //    support.IsChecked = true;
                    //}
                    //lvItem.Tag = support; 



                }


            }
        }
        #endregion


        #region Static

        /// <summary>
        /// Create GridViewColumn with CellTemplate is Checkbox
        /// </summary>
        /// <returns></returns>
        public static GridViewColumn GetGridViewColumnCheckBox()//this ListView listView ,  int[]indexArray
        {
            GridViewColumn gridViewColumn = new GridViewColumn();

            DataTemplate dataTemplate = GetDataTemplateCheckBoxColumn();
            gridViewColumn.CellTemplate = dataTemplate;

            return gridViewColumn;
        }
        #endregion



        private static DataTemplate GetDataTemplateCheckBoxColumn()
        {

            MemoryStream sr = null;

            ParserContext pc = null;

            string xaml = string.Empty;

            xaml = @"<DataTemplate >
						<CheckBox IsChecked=""{Binding Path=Tag.IsChecked,Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"" 
                                  IsEnabled=""{Binding Path=Tag.IsEnabled,Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}""
                                    x:Name=""checkBoxDataTemplateColumn"">
						</CheckBox>
					</DataTemplate>";

            sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

            pc = new ParserContext();

            pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");

            pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

            DataTemplate datatemplate = (DataTemplate)XamlReader.Load(sr, pc);



            return datatemplate;
        }



        public class SupportCheckBoxTag : INotifyPropertyChanged
        {

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged(String info)
            {
                PropertyChangedEventHandler eventhandler = (PropertyChangedEventHandler)PropertyChanged;
                if (eventhandler != null)
                {
                    eventhandler(this, new PropertyChangedEventArgs(info));

                }
            }

            #endregion

            private Boolean isChecked;
            public Boolean IsChecked
            {
                get
                {
                    return isChecked;
                }
                set
                {
                    isChecked = value;
                    OnPropertyChanged("IsChecked");
                }
            }

            private Boolean isEnabled;
            public Boolean IsEnabled
            {
                get
                {
                    return isEnabled;
                }
                set
                {
                    isEnabled = value;
                    OnPropertyChanged("IsEnabled");
                }
            }

            public SupportCheckBoxTag()
            {
                IsChecked = false;
                IsEnabled = true;
            }

        }
        #endregion
    }
}
